home *** CD-ROM | disk | FTP | other *** search
- /*
- Little Smalltalk, version 2
-
- Unix specific input and output routines
- written by tim budd, January 1988
-
- v3.1.0
- ------
- Converted for use with Macintosh by Julian Barkway,
- ©May 1994, all rights reserved.
- */
-
- #include <stdio.h>
-
- #include <string.h>
- #include "env.h"
- #include "memory.h"
- #include "names.h"
- #include "LStResources.h"
-
- #include "macio.h"
- #include "memory.proto.h"
- #include "fileIn.proto.h"
- #include "news.proto.h"
- # ifdef TCL
- # include "tclprim.proto.h"
- # else
- # include "winprim.proto.h"
- # endif
-
- static long fr(short fnum, char *p, long s);
- static void fw(short fnum, char *p, long s);
-
- struct {
- int di;
- object cl;
- short ds;
- } dummyObject;
-
-
-
- //===========================================================
- // Return a full pathname given the directory ID and Vol Ref.
- //===========================================================
- void getPathName (short volRef, long dirID, char *fullPath)
- {
- CInfoPBRec catInfo;
- Str255 dirName;
- OSErr osErr;
-
- fullPath [0] = '\0';
- catInfo.dirInfo.ioDrParID = dirID;
- catInfo.dirInfo.ioNamePtr = dirName;
- do {
- catInfo.dirInfo.ioVRefNum = volRef;
- catInfo.dirInfo.ioFDirIndex = -1;
- catInfo.dirInfo.ioDrDirID = catInfo.dirInfo.ioDrParID;
- osErr = PBGetCatInfo (&catInfo, FALSE);
- PtoCstr (dirName);
- strcat ((char *)dirName, ":");
- strcat ((char *)dirName, fullPath);
- strcpy (fullPath, (char *)dirName);
- } while (catInfo.dirInfo.ioDrDirID != 2);
- }
-
-
-
- //======================================================
- // Return a full pathname given the working directory ID
- //======================================================
- void getPathNameFromWD (long dirID, char *fullPath)
- {
- WDPBRec wdInfo;
- OSErr osErr;
-
- fullPath [0] = '\0';
- wdInfo.ioNamePtr = NULL;
- wdInfo.ioVRefNum = (short)dirID;
- wdInfo.ioWDIndex = 0;
- wdInfo.ioWDProcID = 0;
- osErr = PBGetWDInfo (&wdInfo, FALSE);
- if (osErr != noErr)
- return;
-
- getPathName (wdInfo.ioWDVRefNum, wdInfo.ioWDDirID, fullPath);
- }
-
-
- //=========================================================
- // A version of fgets () using Mac, rather than C, file io.
- // (Probably better to read in the whole file, then parcel
- // lines out as required...)
- //=========================================================
- char *mac_fgets (char *buf, short n, FILE *fd)
- {
- short i = 0;
- long outCt;
- OSErr osErr;
-
- outCt = 1;
- osErr = FSRead (fd->fileRef, &outCt, buf + i);
- if (osErr != 0)
- return NULL;
-
- while ( (buf [i] != '\n')
- && (buf [i] != '\r')
- && (i < n) ) {
- i++;
- FSRead (fd->fileRef, &outCt, buf + i);
- }
-
- if (buf [i] == '\n')
- buf [i] = '\r';
- buf [i + 1] = '\0';
-
- return buf;
- }
-
-
- //=========================================================
- // A version of fputs () using Mac, rather than C, file io.
- //=========================================================
- int mac_fputs (char *str, FILE *fd)
- {
- long outCt;
- OSErr osErr;
-
- outCt = (long)strlen (str);
- osErr = FSWrite (fd->fileRef, &outCt, str);
- if (osErr < 0)
- return EOF;
-
- return 0;
- }
-
-
- //=======================================================
- // imageRead - read in an object image
- // we toss out the free lists built initially,
- // reconstruct the linkages, then rebuild the free
- // lists around the new objects.
- // The only objects with nonzero reference counts
- // will be those reachable from either symbols
- //=======================================================
- static long fr (short fnum, char *p, long s)
- {
- OSErr r;
- long ct = s;
-
- r = FSRead (fnum, &ct, p);
- if ( r != 0L) {
- if (ct != s && r != eofErr)
- sysError ("imageRead count error", "");
- }
-
- return r;
- }
-
- noreturn imageRead (short fnum)
- {
- short i, size;
- object *mBlockAlloc ();
-
- fr (fnum, (char *) &symbols, (long)sizeof(object));
- i = 0;
- while (fr (fnum, (char *)&dummyObject, (long)sizeof (dummyObject)) != eofErr) {
- i = dummyObject.di;
-
- if ((i < 0) || (i > ObjectTableMax))
- sysError("reading index out of range","");
-
- objectTable [i].class = dummyObject.cl;
- if ( ( objectTable [i].class < 0)
- || ((objectTable [i].class >> 1) > ObjectTableMax) ) {
- //****** fprintf ("index %d\n", dummyObject.cl);
- sysError ("class out of range", "imageRead");
- }
-
- objectTable [i].size = size = dummyObject.ds;
- if (size < 0)
- size = ((- size) + 1) / 2;
- if (size != 0) {
- objectTable [i].memory = mBlockAlloc ((int) size);
- fr (fnum, (char *) objectTable [i].memory,
- sizeof (object) * (int) size);
- }
- else
- objectTable[i].memory = (object *) 0;
- }
-
- visit(symbols); /* now restore ref counts, getting rid of unneeded junk */
- setFreeLists(); /* toss out the old free lists, build new ones */
- }
-
- //=======================================================
- // imageWrite - write out an object image
- //=======================================================
-
- static void fw (short fnum, char *p, long s)
- {
- long ct = s;
- OSErr r;
-
- r = FSWrite (fnum, &ct, p);
- if ( r != 0L
- && ct != s )
- sysError ("imageWrite size error", "");
- }
-
- void imageWrite (short fnum)
- {
- short i, size;
-
- fw (fnum, (char *)&symbols, (long)sizeof (object));
-
- for (i = 0; i < ObjectTableMax; i++) {
- if (objectTable [i].referenceCount > 0) {
- dummyObject.di = i;
- dummyObject.cl = objectTable [i].class;
- dummyObject.ds = size = objectTable [i].size;
- fw (fnum, (char *)&dummyObject, sizeof (dummyObject));
- if (size < 0)
- size = ((- size) + 1) / 2;
- if (size != 0) {
- fw (fnum, (char *)objectTable [i].memory,
- (long)sizeof (object) * size);
- }
- }
- }
- }
-
-
-
- #define MAXFILES 20
- #define OPEN_READ 1
- #define OPEN_WRITE 2
-
- /* we assume this is initialized to NULL */
- static FILE fp [MAXFILES];
-
- //===============================================================================
- // Following function just returns the file pointer associated with a file number
- //===============================================================================
- FILE *getFilePointer (short fileNum)
- {
- return &(fp [fileNum]);
- }
-
-
- //===============================================================================
- // Create a file to write to.
- //===============================================================================
- OSErr createFile (Str255 *fname, short ft)
- {
- unsigned long fileType, secs;
- Str255 tmp;
-
- stFileTypeToMac (ft, fileType);
-
- /* Create temporary file - hopefully with a unique file name! */
- /* We'll rename it later... */
- PtoCstr ((unsigned char *)fname);
- strcat ((char *)fname, "|");
- GetDateTime (&secs);
- NumToString (secs, tmp);
- PtoCstr (tmp);
- strcat ((char *)fname, (char *)tmp);
- CtoPstr ((char *)fname);
- return Create ((unsigned char *)fname, 0, kCreator, fileType);
- }
-
-
- //===============================================================================
- // Open a file for reading or writing.
- //===============================================================================
- OSErr openFile (FILE *fd, char *fname, char *openParms, short ftype)
- {
- OSErr osErr;
-
- CtoPstr (fname);
- fd->openMode = OPEN_READ;
- if (openParms [0] == 'w') {
- osErr = createFile ((Str255 *)fname, ftype);
- if (osErr != 0L) {
- fd->openMode = 0;
- goto error_exit; /* Create failed */
- }
- fd->openMode = OPEN_WRITE;
- }
- osErr = FSOpen ((unsigned char *)fname, 0, &(fd->fileRef));
- if (osErr != 0)
- fd->openMode = 0;
-
- error_exit:
- PtoCstr ((unsigned char *)fname);
- return osErr;
- }
-
-
- void closeFile (FILE *fd, char *fname)
- {
- long fsize;
- Str255 tmp;
- char *str;
- OSErr osErr;
-
- if (fd->fileRef == 0)
- return;
-
- FSClose (fd->fileRef);
- if (fd->openMode == OPEN_WRITE) {
- FlushVol (NULL, 0);
- GetEOF (fd->fileRef, &fsize); /* Set file size */
- SetEOF (fd->fileRef, fsize);
- strcpy ((char *)tmp, fname);
- strtok ((char *)tmp, "|"); /* Clip off our unique ID */
- CtoPstr (fname);
- CtoPstr ((char *)tmp);
- osErr = FSDelete (tmp, 0);
- if (osErr == 0L || osErr == fnfErr) {
- Rename ((unsigned char *)fname, 0,tmp);
- PtoCstr ((unsigned char *)fname);
- PtoCstr (tmp);
- strcpy (fname, (char *)tmp);
- }
- }
- fd->openMode = 0;
- fd->fileRef = 0;
- }
-
-
-
- //=========================================================
- // Mac dependent file I/O primitives;
- // basically, file numbers are all kept in a large array.
- // File operations then just give an index into this array
- //=========================================================
- object ioPrimitive (int number, object *arguments)
- {
- short i, j;
- char *p, buffer [1024], *openParms;
- object returnedObject;
- OSErr osErr;
-
- returnedObject = nilobj;
-
- i = intValue (arguments [0]); /* p0 = Smalltalk file number */
- switch (number) {
- case 0: /* file open: p1 = fname; p2 = open type; p3 = file type */
- osErr = openFile (&fp [i],
- charPtr (arguments [1]), charPtr (arguments [2]),
- intValue (arguments [3]));
- if (osErr != 0L)
- returnedObject = nilobj; /* Open failed */
- else
- returnedObject = newInteger (i);
- break;
-
- case 1:
- closeFile (&fp [i], charPtr (arguments [1]));
- break;
-
- case 2: /* file size */
- case 3: /* file in */
- if (fp [i].fileRef)
- fileIn (&fp [i], true);
- break;
-
- case 4: /* was Get Character - now Delete File */
- p = charPtr (arguments [1]); /* Pathname of file to delete */
- CtoPstr (p);
- osErr = FSDelete ((unsigned char *)p, 0);
- if (osErr == 0L)
- returnedObject = falseobj;
- else
- returnedObject = trueobj; /* returns true if error */
- break;
-
- case 5: /* get string */
- if (fp [i].fileRef == 0)
- break;
- j = 0;
- buffer [j] = '\0';
- while (1) {
- if (mac_fgets (&buffer [j], 512, &fp [i]) == NULL)
- return nilobj; /* end of file */
- j = strlen(buffer)-1;
- if (buffer[j] != '\\') // Unix???
- break;
- /* else we loop again */
- }
- returnedObject = newStString (buffer);
- break;
-
- case 7: /* write an object image */
- if (fp [i].fileRef)
- imageWrite (fp [i].fileRef);
- returnedObject = trueobj;
- break;
-
- case 8: /* write a string to a file with no <cr> */
- case 9: /* write a string, adding a <cr> */
- //****** if (! fp[i])
- //****** break;
- mac_fputs (charPtr (arguments [1]), &fp [i]);
- if (number == 9)
- mac_fputs ("\r", &fp [i]);
- break;
-
- default:
- sysError ("unknown primitive", "filePrimitive");
- }
-
- return returnedObject;
- }
-
-